﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Battleship
{
    /**
     * Class tính biên độ lắc
     */
    class ShakingAmptitude
    {
        private ExcelReader reader = new ExcelReader();
        private double biendolac;

        // Bảng tra dùng cho tính các giá trị m1, m2, m3
        private Dictionary<double, double> n1m0_Map = new Dictionary<double, double>()
        {
            {0.1, 0.42}, {0.15, 0.52}, {0.25, 0.78}, {0.5, 1.38}, 
            {0.75, 1.94}, {1.0, 2.4}, {1.5, 3.0}, 
            {2.0, 3.3}, {2.5, 3.5}, {3.0, 3.6}
        };

        private Dictionary<double, double> Bdm2_Map = new Dictionary<double, double>() 
        { 
            {2.5, 1.0}, {3.0, 2.9}, {3.5, 0.81}, {4.0, 0.78}, 
            {5.0, 0.81}, {6.0, 0.87}, {7.0, 0.92}, 
            {8.0, 0.96}, {9.0, 0.9}, {10.0, 1.00}
        };

        private Dictionary<double, double> CBm3_Map = new Dictionary<double, double>()
        {
            {0.45, 1.00}, {0.50, 0.95}, {0.55, 0.86}, 
            {0.60, 0.77}, {0.65, 0.72}, {0.70, 0.69}, 
            {0.75, 0.67}, {0.80, 0.66}
        };

        private Dictionary<double, double> Shaking_Map = new Dictionary<double, double>()
        {
            {0.4, 9.0}, {0.6, 10.0}, {0.8, 13.0}, 
            {1.0, 17.0}, {1.2, 20.0}, {1.4, 23.0},
            {1.6, 24.0}, {18.0, 24.0}
        };

        // Gía trị tạm gán
        private double V = 425.576;
        private double Zg = 2.2159;

        public ShakingAmptitude(double V, double Zg)
        {
            this.V = V;
            this.Zg = Zg;
            calculate();
        }

        public void calculate()
        {
            HydrostaticInterpolate HI = new HydrostaticInterpolate();
            double h0 = HI.hydroInterpolate(V, Constants.r);
            double n1 = (h0 * Constants.B) / (Zg * Math.Pow(V, 1.0 / 3));
            double m0 = 0.0;
            if (n1 <= Constants.n1Min)
            {
                m0 = n1m0_Map[Constants.n1Min];
            }
            else if (n1 >= Constants.n1Max)
            {
                m0 = n1m0_Map[Constants.n1Max];
            }
            else
            {
                m0 = Formulas.linearInterpolation(n1, n1m0_Map.Keys.ToArray<double>(),
                    n1m0_Map.Values.ToArray<double>());
            }
            double m1 = m0 / Math.Sqrt(h0);

            /** Tính m2 **/
            double d = HI.hydroInterpolate(V, Constants.DI);
            double Bd = Constants.B / d;
            double m2 = 0.0;
            if (Bd <= Constants.BdMin)
            {
                m2 = Bdm2_Map[Constants.BdMin];
            }
            else if (Bd >= Constants.BdMax)
            {
                m2 = Bdm2_Map[Constants.BdMax];
            }
            else
            {
                m2 = Formulas.linearInterpolation(Bd, Bdm2_Map.Keys.ToArray<double>(),
                    Bdm2_Map.Values.ToArray<double>());
            }

            /** Tính m3 **/
            double CB = HI.hydroInterpolate(V, Constants.CB);
            double m3 = 0.0;
            if (CB <= Constants.CBMin)
            {
                m3 = CBm3_Map[Constants.CBMin];
            }
            else if (CB >= Constants.CBMax)
            {
                m3 = CBm3_Map[Constants.CBMax];
            }
            else
            {
                m3 = Formulas.linearInterpolation(CB, CBm3_Map.Keys.ToArray<double>(),
                    CBm3_Map.Values.ToArray<double>());
            }

            /** Tính m **/
            double m = m1 * m2 * m3;
            double phi = Formulas.linearInterpolation(m, Shaking_Map.Keys.ToArray<double>(),
                Shaking_Map.Values.ToArray<double>());
            this.biendolac = phi * 0.75;
        }

        public double Biendolac
        {
            get { return biendolac; }
            set { biendolac = value; }
        }
    }
}
